package com.mylib.libcore.utils;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

import androidx.core.app.ActivityCompat;

import com.mylib.libcore.AppContext;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import static com.mylib.libcore.config.AppSPKeyConfig.APP_OA_ID;

/**
 * 获取oaid
 */
public class DevicesIDUtil {


    /**
     * 获取Oaid
     * @return 获取Oaid
     */
    public static String getOaid() {
        String oaid = AppContext.getInstance().getAppPreferenceForever().getAppOAID();
        if(UIUtils.isEmpty(oaid)) oaid="";
        Log.d("getOaid",oaid+"");
        return oaid;
    }

    /**
     * 获取Oaid或imei作为设备id-优先aaid
     * @return 获取Oai
     */
    public static String getIDByOaIDImeID(Context context) {
        String deviceID = AppContext.getInstance().getAppPreferenceForever().getAppOAID();
        if(UIUtils.isEmpty(deviceID)){
            deviceID=getIMEI(context);
        }
        Log.d("getIDByOaIDImeID",deviceID+"");
        return deviceID;
    }

    /**
     * 获取设备id
     * @return 获取Oai
     */
    public static String getOnlyID(Context context){
        String onlyId = getANDROID_ID(context)+getSerialNumber()+getUniquePsuedoID();
        Log.d("getOnlyID",onlyId+"");
        if(UIUtils.isEmpty(onlyId)){
            onlyId = getUUID();
        }
        if(UIUtils.isEmpty(onlyId)){
            return "";
        }else {
            return getMD5Str(onlyId);
        }
    }

    @SuppressLint("MissingPermission")
    private static String getUUID() {
        try {
            String serial = null;

            String m_szDevIDShort = "35" +
                    Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +

                    ((null != Build.CPU_ABI) ? Build.CPU_ABI.length() : 0) % 10 +

                    Build.DEVICE.length() % 10 + Build.DISPLAY.length() % 10 +

                    Build.HOST.length() % 10 + Build.ID.length() % 10 +

                    Build.MANUFACTURER.length() % 10 + Build.MODEL.length() % 10 +

                    Build.PRODUCT.length() % 10 + Build.TAGS.length() % 10 +

                    Build.TYPE.length() % 10 + Build.USER.length() % 10; //13 位

            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
                try {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        serial =  Build.getSerial()+"";
                    } else {
                        serial = Build.SERIAL;
                    }
                    //API>=9 使用serial号
                    return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
                } catch (Exception exception) {
                    serial = "serial" + UUID.randomUUID().toString(); // 随便一个初始化
                }
            } else {
                serial = android.os.Build.UNKNOWN + UUID.randomUUID().toString(); // 随便一个初始化
            }

            //使用硬件信息拼凑出来的15位号码
            return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
        }catch (Exception e){
            return "";
        }

    }

    /**
     * 获取Oaid或imei作为设备id-androidid-优先aaid,imei,androidid
     * @return 获取Oai
     */
    public static String getDeviceIDAll(Context context) {
        String deviceID = AppContext.getInstance().getAppPreferenceForever().getAppOAID();
        if(UIUtils.isEmpty(deviceID)){
            deviceID=getIMEI(context);
        }
        if(UIUtils.isEmpty(deviceID)){
            deviceID = getOnlyID(context);
        }
        Log.d("getDeviceIDAll",deviceID+"");
        return deviceID+"";
    }


    /**
     * 获取IMEI.
     * @return
     */
    public static String getIMEI(Context context) {
        try {
            String imeiID = "";
            List<String> listID = getTwoIMEI(context);
            if(!UIUtils.isEmpty(listID) && listID.size()>0){
                for(String id: listID){
                    if(!UIUtils.isEmpty(id)){
                        imeiID =id;
                        return imeiID;
                    }
                }
            }

            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                return null;
            }
            if (telephonyManager.getDeviceId() == null) {
                return null;
            } else {
                return telephonyManager.getDeviceId();
            }
        }catch (Exception e){
            return "";
        }

    }

    /**
     * 获取双IMEI.
     * @return
     */
    public static List<String> getTwoIMEI(Context context) {

        try {
            TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            @SuppressLint("MissingPermission") String imei = tm.getDeviceId();
            List<String> IMEIS = new ArrayList<String>();
            if (checkimei(imei.trim())) {
                IMEIS.add(imei.trim());
            }

            try{
                @SuppressLint("WrongConstant") TelephonyManager telephonyManager1 = (TelephonyManager)context.getSystemService("phone1");
                @SuppressLint("MissingPermission") String imeiphone1=   telephonyManager1.getDeviceId();
                if (imeiphone1 != null && checkimei(imeiphone1)) {
                    if (!IMEIS.contains(imeiphone1)) {
                        IMEIS.add(imeiphone1);
                    }
                }
            }  catch (Exception e) {

            }
            try{
                @SuppressLint("WrongConstant") TelephonyManager telephonyManager2 = (TelephonyManager)context.getSystemService("phone2");
                @SuppressLint("MissingPermission") String imeiphone2=   telephonyManager2.getDeviceId();
                if (imeiphone2 != null && checkimei(imeiphone2)) {
                    if (!IMEIS.contains(imeiphone2)) {
                        IMEIS.add(imeiphone2);
                    }
                }
            }  catch (Exception e) {

            }

            List<String> imeis = IMEI_initQualcommDoubleSim(context);
            if (imeis != null && imeis.size() > 0) {
                for (String item : imeis) {
                    if (!IMEIS.contains(item)) {
                        IMEIS.add(item);
                    }
                }
            }

            imeis = IMEI_initMtkSecondDoubleSim(context);
            if (imeis != null && imeis.size() > 0) {
                for (String item : imeis) {
                    if (!IMEIS.contains(item)) {
                        IMEIS.add(item);
                    }
                }
            }
            imeis = IMEI_initMtkDoubleSim(context);
            if (imeis != null && imeis.size() > 0) {
                for (String item : imeis) {
                    if (!IMEIS.contains(item)) {
                        IMEIS.add(item);
                    }
                }
            }
            imeis = IMEI_initSpreadDoubleSim(context);
            if (imeis != null && imeis.size() > 0) {
                for (String item : imeis) {
                    if (!IMEIS.contains(item)) {
                        IMEIS.add(item);
                    }
                }
            }

            Log.d("two_imei",IMEIS.toString()+"");
            if(!UIUtils.isEmpty(IMEIS) && IMEIS.size()>0){
                return IMEIS;
            }else {
                return null;
            }

        } catch (Exception e) {
            return null;
        }
    }

    //检查ime
    private static Boolean checkimei(String IMEI) {
        Integer LEN = IMEI.length();
        if (LEN > 10 && LEN < 20 && !checkimeisame(IMEI.trim())) {
            return true;
        }
        return false;
    }

    //检查两个ime是否相同
    private static Boolean checkimeisame(String imei) {
        char firstchar = '0';
        if (imei.length() > 0) {
            firstchar = imei.charAt(0);
        }
        Boolean issame = true;
        for (int i = 0; i < imei.length(); i++) {
            char ch = imei.charAt(i);
            if (firstchar != ch) {
                issame = false;
                break;
            }
        }
        return issame;
    }

    private  static List<String> IMEI_initMtkDoubleSim(Context context) {
        try {
            TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            Class<?> c = Class.forName("com.android.internal.telephony.Phone");
            Integer simId_1, simId_2;
            try {
                java.lang.reflect.Field fields1 = c.getField("GEMINI_SIM_1");
                fields1.setAccessible(true);
                simId_1 = (Integer) fields1.get(null);
                java.lang.reflect.Field fields2 = c.getField("GEMINI_SIM_2");
                fields2.setAccessible(true);
                simId_2 = (Integer) fields2.get(null);
            } catch (Exception ex) {
                simId_1 = 0;
                simId_2 = 1;
            }

            java.lang.reflect.Method m1 = TelephonyManager.class
                    .getDeclaredMethod("getDeviceIdGemini", int.class);
            String imei_1 = ((String) m1.invoke(tm, simId_1)).trim();
            String imei_2 = ((String) m1.invoke(tm, simId_2)).trim();


            List<String> imeis = new ArrayList<String>();
            if (checkimei(imei_1)) {
                imeis.add(imei_1);
            }
            if (checkimei(imei_2)) {
                imeis.add(imei_2);
            }
            return imeis;
        } catch (Exception e) {
            // ��MTK
            return null;
        }
    }

    private static List<String> IMEI_initSpreadDoubleSim(Context context) {
        try {
            Class<?> c = Class.forName("com.android.internal.telephony.PhoneFactory");
            java.lang.reflect.Method m = c.getMethod("getServiceName",
                    String.class, int.class);
            String spreadTmService = (String) m.invoke(c,
                    Context.TELEPHONY_SERVICE, 1);

            TelephonyManager tm = (TelephonyManager) context
                    .getSystemService(Context.TELEPHONY_SERVICE);
            // String imsi_1 = tm.getSubscriberId();
            @SuppressLint("MissingPermission") String imei_1 = (tm.getDeviceId()).trim();
            // Integer phoneType_1 = tm.getPhoneType();
            TelephonyManager tm1 = (TelephonyManager) context
                    .getSystemService(spreadTmService);
            // String imsi_2 = tm1.getSubscriberId();
            @SuppressLint("MissingPermission") String imei_2 = (tm1.getDeviceId()).trim();

            List<String> imeis = new ArrayList<String>();
            if (checkimei(imei_1)) {
                imeis.add(imei_1);
            }
            if (checkimei(imei_2)) {
                imeis.add(imei_2);
            }
            return imeis;

        } catch (Exception e) {
            return null;
        }
    }

    private static List<String> IMEI_initMtkSecondDoubleSim(Context context) {
        try {
            TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            Class<?> c = Class.forName("com.android.internal.telephony.Phone");

            Integer simId_1, simId_2;
            try {
                java.lang.reflect.Field fields1 = c.getField("GEMINI_SIM_1");
                fields1.setAccessible(true);
                simId_1 = (Integer) fields1.get(null);
                java.lang.reflect.Field fields2 = c.getField("GEMINI_SIM_2");
                fields2.setAccessible(true);
                simId_2 = (Integer) fields2.get(null);
            } catch (Exception ex) {
                simId_1 = 0;
                simId_2 = 1;
            }

            java.lang.reflect.Method mx = TelephonyManager.class.getMethod(
                    "getDefault", int.class);
            TelephonyManager tm1 = (TelephonyManager) mx.invoke(tm, simId_1);
            TelephonyManager tm2 = (TelephonyManager) mx.invoke(tm, simId_2);

            @SuppressLint("MissingPermission") String imei_1 = (tm1.getDeviceId()).trim();
            @SuppressLint("MissingPermission") String imei_2 = (tm2.getDeviceId()).trim();

            List<String> imeis = new ArrayList<String>();
            if (checkimei(imei_1)) {
                imeis.add(imei_1);
            }
            if (checkimei(imei_2)) {
                imeis.add(imei_2);
            }
            return imeis;

        } catch (Exception e) {
            return null;
        }
    }

    public static List<String> IMEI_initQualcommDoubleSim(Context context) {
        try {
            TelephonyManager tm = (TelephonyManager) context
                    .getSystemService(Context.TELEPHONY_SERVICE);
            Class<?> cx = Class.forName("android.telephony.MSimTelephonyManager");
            @SuppressLint("WrongConstant") Object obj = context.getSystemService("phone_msim");
            Integer simId_1 = 0;
            Integer simId_2 = 1;
            //
            // java.lang.reflect.Method mx = cx.getMethod("getDataState");
            // // int stateimei_1 = (Integer) mx.invoke(cx.newInstance());
            // int stateimei_2 = tm.getDataState();
            // java.lang.reflect.Method mde = cx.getMethod("getDefault");
            java.lang.reflect.Method md = cx.getMethod("getDeviceId", int.class);
            // java.lang.reflect.Method ms = cx.getMethod("getSubscriberId",
            // int.class);
            // java.lang.reflect.Method mp = cx.getMethod("getPhoneType");

            // Object obj = mde.invoke(cx);

            String imei_1 = ((String) md.invoke(obj, simId_1)).trim();
            String imei_2 = ((String) md.invoke(obj, simId_2)).trim();

            // String imsi_1 = (String) ms.invoke(obj, simId_1);
            // String imsi_2 = (String) ms.invoke(obj, simId_2);

            // int statephoneType_1 = tm.getDataState();
            // int statephoneType_2 = (Integer) mx.invoke(obj);

            List<String> imeis = new ArrayList<String>();
            if (checkimei(imei_1)) {
                imeis.add(imei_1);
            }
            if (checkimei(imei_2)) {
                imeis.add(imei_2);
            }
            return imeis;

            // Log.e("tag", statephoneType_1 + "---" + statephoneType_2);

            // Class<?> msc = Class.forName("android.telephony.MSimSmsManager");
            // for (Method m : msc.getMethods()) {
            // if (m.getName().equals("sendTextMessage")) {
            // m.getParameterTypes();
            // }
            // Log.e("tag", m.getName());
            // }

        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取手机序列号
     * @return 手机序列号
     */
    @SuppressLint({"NewApi", "MissingPermission"})
    public static String getSerialNumber() {
        String serial = "";
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {//9.0+
                serial = Build.getSerial();
            } else if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {//8.0+
                serial = Build.SERIAL;
            } else {//8.0-
                Class<?> c = Class.forName("android.os.SystemProperties");
                Method get = c.getMethod("get", String.class);
                serial = (String) get.invoke(c, "ro.serialno");
            }
        } catch (Exception e) {
            e.printStackTrace();

        }
        return serial;
    }


    public static String getANDROID_ID(Context context){
        String ANDROID_ID="";
        try {
            ANDROID_ID = Settings.System.getString(context.getContentResolver(), Settings.System.ANDROID_ID);
            if(UIUtils.isEmpty(ANDROID_ID)){
                return "";
            }
        }catch (Exception e){
            return "";
        }

        return  ANDROID_ID;
    }


    public static String getUniquePsuedoID(){
        try {
            String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);


            String serial = null;
            try
            {
                serial = Build.class.getField("SERIAL").get(null).toString();

                return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
            }
            catch (Exception e)
            {
                serial = "serial";
            }

            return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
        }catch (Exception e){
            return "";
        }
    }


    private static String getMD5Str(String str) {
        MessageDigest messageDigest = null;
        try {
            messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            messageDigest.update(str.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
//            System.out.println("NoSuchAlgorithmException caught!");
            System.exit(-1);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        byte[] byteArray = messageDigest.digest();
        StringBuffer md5StrBuff = new StringBuffer();
        for (int i = 0; i < byteArray.length; i++) {
            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
                md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
            else
                md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
        }
        return md5StrBuff.toString();
    }

}
